bitkeeper revision 1.1159.79.3 (414c2251mzKL-aQm0trJwzhIuFOv8Q)
authorkaf24@freefall.cl.cam.ac.uk <kaf24@freefall.cl.cam.ac.uk>
Sat, 18 Sep 2004 11:56:01 +0000 (11:56 +0000)
committerkaf24@freefall.cl.cam.ac.uk <kaf24@freefall.cl.cam.ac.uk>
Sat, 18 Sep 2004 11:56:01 +0000 (11:56 +0000)
Stricter skbuff checking in net backend driver. Ensure skbs to be transferred
to other domains are allocated out of our secure cache.

linux-2.6.8.1-xen-sparse/arch/xen/kernel/skbuff.c
linux-2.6.8.1-xen-sparse/drivers/xen/netback/netback.c

index 0c246945841602c7f3ab96fc82bf72dd431a1297..9f18afe22aa4e6b141e3c2b88bd996342fe44352 100644 (file)
@@ -17,7 +17,8 @@
 
 EXPORT_SYMBOL(__dev_alloc_skb);
 
-static kmem_cache_t *skbuff_cachep;
+/* Referenced in netback.c. */
+/*static*/ kmem_cache_t *skbuff_cachep;
 
 struct sk_buff *__dev_alloc_skb(unsigned int length, int gfp_mask)
 {
index 242f5007808634bebb23852ee8d519c21af07818..2d8902cbb3179875f5b11206ac115f36696f17e4 100644 (file)
@@ -108,6 +108,21 @@ static inline void maybe_schedule_tx_action(void)
         tasklet_schedule(&net_tx_tasklet);
 }
 
+/*
+ * A gross way of confirming the origin of an skb data page. The slab
+ * allocator abuses a field in the page struct to cache the kmem_cache_t ptr.
+ */
+static inline int is_xen_skb(struct sk_buff *skb)
+{
+    extern kmem_cache_t *skbuff_cachep;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+    kmem_cache_t *cp = (kmem_cache_t *)virt_to_page(skb->head)->lru.next;
+#else
+    kmem_cache_t *cp = (kmem_cache_t *)virt_to_page(skb->head)->list.next;
+#endif
+    return (cp == skbuff_cachep);
+}
+
 int netif_be_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
     netif_t *netif = (netif_t *)dev->priv;
@@ -122,15 +137,12 @@ int netif_be_start_xmit(struct sk_buff *skb, struct net_device *dev)
     /*
      * We do not copy the packet unless:
      *  1. The data is shared; or
-     *  2. It spans a page boundary; or
-     *  3. We cannot be sure the whole data page is allocated.
+     *  2. The data is not allocated from our special cache.
      * The copying method is taken from skb_copy().
      * NB. We also couldn't cope with fragmented packets, but we won't get
      *     any because we not advertise the NETIF_F_SG feature.
      */
-    if ( skb_shared(skb) || skb_cloned(skb) || 
-         (((unsigned long)skb->end ^ (unsigned long)skb->head) & PAGE_MASK) ||
-         ((skb->end - skb->head) < (PAGE_SIZE/2)) )
+    if ( skb_shared(skb) || skb_cloned(skb) || !is_xen_skb(skb) )
     {
         struct sk_buff *nskb = dev_alloc_skb(PAGE_SIZE);
         int hlen = skb->data - skb->head;